package com.syh.jn.scm.infrastructure.repository.impl.upstream.logistics;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.jn.scm.domain.upstream.entity.logistics.UpLogisticsBill;
import com.syh.jn.scm.domain.upstream.entity.logistics.UpLogisticsBillItem;
import com.syh.jn.scm.domain.upstream.repository.logistics.UpLogisticsBillRepository;
import com.syh.jn.scm.dto.upstream.logistics.UpLogisticsBillVo;
import com.syh.jn.scm.infrastructure.repository.model.logistics.LogisticsBillItemModel;
import com.syh.jn.scm.infrastructure.repository.model.logistics.LogisticsBillModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by soci.song on 2018/11/2.
 */
@Repository
public class UpLogisticsBillRepositoryImpl extends AbstractAggregateRepository<UpLogisticsBill, LogisticsBillModel, Long> implements UpLogisticsBillRepository {


  @Override
  public Long add(UpLogisticsBill logisticsBill) {
    Long id = super.add(logisticsBill);
    this.saveBillItems(id, logisticsBill.getItems());
    return id;
  }

  @Override
  public void update(UpLogisticsBill logisticsBill) {
    super.update(logisticsBill);
    this.removeItems(logisticsBill.getId());
    this.saveBillItems(logisticsBill.getId(), logisticsBill.getItems());
  }

  /**
   * 修改订单
   */
  @Override
  public void updateStatus(UpLogisticsBill logisticsBill) {
    super.update(logisticsBill);
  }

  /**
   * 保存当前物流单对应的item
   *
   * @param id
   * @param items
   */
  private void saveBillItems(Long id, List<UpLogisticsBillItem> items) {
    items.stream().forEach(item -> {
      LogisticsBillItemModel itemModel = new LogisticsBillItemModel();
      ExtBeanUtils.copyProperties(item, itemModel);
      itemModel.setLogisticsBillId(id);
      this.hibernateTemplate.save(itemModel);
    });
  }

  /**
   * 删除物流单
   *
   * @param aLong
   */
  @Override
  public void removeById(Long aLong) {
    super.removeById(aLong);
    this.removeItems(aLong);
  }

  private void removeItems(Long id) {
    StringBuffer hql = new StringBuffer();
    hql.append("from LogisticsBillItemModel model where model.logisticsBillId = ?");
    List<LogisticsBillItemModel> items = (List<LogisticsBillItemModel>) this.hibernateTemplate.find(hql.toString(), id);
    items.forEach(item -> {
      this.hibernateTemplate.delete(item);
    });
  }

  @Override
  public UpLogisticsBill getById(Long id) {
    UpLogisticsBill bill = super.getById(id);
    if (bill == null) {
      return bill;
    }
    bill.setItems(this.getItemsByLogisticsBillId(id));
    return bill;
  }

  @Override
  public List<UpLogisticsBillItem> getItemsByLogisticsBillId(Long id) {
    StringBuffer hql = new StringBuffer();
    hql.append("from LogisticsBillItemModel model where model.logisticsBillId = ?");
    List<LogisticsBillItemModel> itemModels = (List<LogisticsBillItemModel>) this.hibernateTemplate.find(hql.toString(), id);
    List<UpLogisticsBillItem> items = new ArrayList<>();
    itemModels.forEach(itemModel -> {
      UpLogisticsBillItem item = new UpLogisticsBillItem();
      ExtBeanUtils.copyProperties(itemModel, item);
      items.add(item);
    });
    return items;
  }

  @Override
  protected SQL getViewSql() {
    return new SQL() {{
      SELECT(SQLAliasGenerateUtil.aliasGenerate(LogisticsBillModel.class, "upLogisticsBill", null),
              "logisticsCompany.NAME as logisticsCompanyName,secondaryBill.ID as secondaryBillId");
      FROM("T_LOGISTICS_BILL AS upLogisticsBill");
      LEFT_OUTER_JOIN(" T_BASE_LOGISTICS logisticsCompany ON upLogisticsBill.LOGISTICS_COMPANY_ID = logisticsCompany.ID");
      LEFT_OUTER_JOIN(" ( SELECT ID, SUBJECT_BILL_ID FROM T_LOGISTICS_BILL WHERE SUBJECT_BILL_ID IS NOT NULL ) secondaryBill ON upLogisticsBill.ID = secondaryBill.SUBJECT_BILL_ID");
    }};
  }

  @Override
  protected Class getViewObject() {
    return UpLogisticsBillVo.class;
  }

  @Override
  protected BaseResolve getViewWrapperResolve(Wrapper wrapper) {
    Map<String, String> params = new HashMap<>();
    params.put("id", "upLogisticsBill.ID");
    params.put("orderType", "upLogisticsBill.ORDER_TYPE");
    params.put("code", "upLogisticsBill.CODE");
    params.put("orderCode", "upLogisticsBill.ORDER_CODE");
    params.put("customerType", "upLogisticsBill.CUSTOMER_TYPE");
    params.put("customerId", "upLogisticsBill.CUSTOMER_ID");
    params.put("logisticsState", "upLogisticsBill.LOGISTICS_STATE");
    params.put("statementState", "upLogisticsBill.STATEMENT_STATE");
    params.put("statementId", "upLogisticsBill.STATEMENT_ID");
    params.put("logisticsType", "upLogisticsBill.LOGISTICS_TYPE");
    params.put("logisticsCompanyId", "upLogisticsBill.LOGISTICS_COMPANY_ID");
    params.put("createTimeStamp", "upLogisticsBill.CREATE_TIME_STAMP");
    params.put("businessEntityId", "upLogisticsBill.BUSINESS_ENTITY_ID");
    ResolveToSQL parse = new ResolveToSQL(wrapper, (propertyName) -> {
      return params.get(propertyName);
    });
    return parse;
  }
}
